#pragma  once

#include "ExternalTools.h"

CTimer CExternalTools::le_myTimer_A;
CTimer CExternalTools::le_myTimer_B;
CTimer CExternalTools::le_myTimer_C;
CTimer CExternalTools::le_myTimer_D;

int CExternalTools::_public_color_for_cimg[3];

//void CRichImage::LoadImageByFileName(const string& strFN_SourceImage)
//{
//	CImg<int> imgIntRGB;
//	CExternalTools::myLoadImage(strFN_SourceImage, imgIntRGB);
//	this->LoadImage(imgIntRGB);
//}
//
//void CRichImage::LoadImageByFileName(const char* strFN_SourceImage)
//{
//	CImg<int> imgIntRGB;
//	CExternalTools::myLoadImage(strFN_SourceImage, imgIntRGB);
//	this->LoadImage(imgIntRGB);
//}

void CExternalTools::OutputTextToImage(
	CImg<int>& dstImgRGB,
	string strText, int x, int y,
	int BgColorR, int BgColorG, int BgColorB,
	int FgColorR, int FgColorG, int FgColorB,
	int FontSize
	)
{
	static int _fgc[3];
	static int _bgc[3];

	int fontsize = 20;
	_fgc[0] = FgColorR;
	_fgc[1] = FgColorG;
	_fgc[2] = FgColorB;
	_bgc[0] = BgColorR;
	_bgc[1] = BgColorG;
	_bgc[2] = BgColorB;
	dstImgRGB.draw_text(strText.c_str(),x,y,_fgc,_bgc,FontSize);
}

void CExternalTools::OutputRectBoxToImage(
	CImg<int>& dstImgRGB,
	const CRectBox<int>& Box,
	int ColorR, int ColorG, int ColorB, int BorderWidth,
	int FontSize, string Title
	)
{
	static int _fgc[3];
	static int _bgc[3];

	bool ret = false;
	int x,y;
	int xa = Box.x;
	int ya = Box.y;
	int xb = Box.x + Box.w - 1;
	int yb = Box.y + Box.h - 1;

	if (xa<0) xa = 0;
	if (ya<0) ya = 0;
	if (xb>=dstImgRGB.dimx()) xb = dstImgRGB.dimx()-1;
	if (yb>=dstImgRGB.dimy()) yb = dstImgRGB.dimy()-1;
	if (xb<xa || yb<ya) return;

	if (dstImgRGB.dimx()>xb && dstImgRGB.dimy()>yb && dstImgRGB.dimz()==1 && dstImgRGB.dimv()==3)
	{
		for ( x = xa; x <= xb; ++x )
			for ( y = 0; y < BorderWidth; ++y )
			{
				dstImgRGB.at(x,ya+y,0,0) = ColorR;
				dstImgRGB.at(x,ya+y,0,1) = ColorG;
				dstImgRGB.at(x,ya+y,0,2) = ColorB;

				dstImgRGB.at(x,yb-y,0,0) = ColorR;
				dstImgRGB.at(x,yb-y,0,1) = ColorG;
				dstImgRGB.at(x,yb-y,0,2) = ColorB;
			}
			for ( y = ya; y <= yb; ++y )
				for ( x = 0; x < BorderWidth; ++x )
				{
					dstImgRGB.at(xa+x,y,0,0) = ColorR;
					dstImgRGB.at(xa+x,y,0,1) = ColorG;
					dstImgRGB.at(xa+x,y,0,2) = ColorB;

					dstImgRGB.at(xb-x,y,0,0) = ColorR;
					dstImgRGB.at(xb-x,y,0,1) = ColorG;
					dstImgRGB.at(xb-x,y,0,2) = ColorB;
				}
				if (Title != "")
				{
					int fontsize = 20;
					_fgc[0] = (ColorR<128 ? 255: 0);
					_fgc[1] = (ColorG<128 ? 255: 0);
					_fgc[2] = (ColorB<128 ? 255: 0);
					_bgc[0] = ColorR;
					_bgc[1] = ColorG;
					_bgc[2] = ColorB;
					dstImgRGB.draw_text(Title.c_str(),xa,ya,_fgc,_bgc,FontSize);
				}
	}
}

void CExternalTools::ConsoleTools::MakeDirectory(
	string strPN_TargetDirectory,
	bool fClean, string strPN_RunningBase)
{
	if (strPN_TargetDirectory == "") return;

	char command[MAX_PATH];

	ClearCurrentLine();
	sprintf_s(command, MAX_PATH, "%smkdir %s >:null", strPN_RunningBase.c_str(), strPN_TargetDirectory.c_str());
	system(command);
	sprintf_s(command, MAX_PATH, "%srmdir /s /q %s >:null", strPN_RunningBase.c_str(), strPN_TargetDirectory.c_str());
	if (fClean) system(command);
	sprintf_s(command, MAX_PATH, "%smkdir %s >:null", strPN_RunningBase.c_str(), strPN_TargetDirectory.c_str());
	system(command);
}

int CExternalTools::ConsoleTools::RunDosCommand(
	string strPN_WorkPath,
	string strCommandLine,
	string strPN_ExeFile
	)
{
	int rv, ret;

	//cout<<"Work Path: "<<strPN_WorkPath<<endl;
	//cout<<"ExeFilePN: "<<strPN_ExeFile<<endl;
	//cout<<"CommandLn: "<<strCommandLine<<endl;
	strCommandLine = strPN_ExeFile + strCommandLine;

	if (strPN_WorkPath=="")
		strPN_WorkPath = ".";

	char fn[MAX_PATH];
	sprintf(fn,"_TEMP_%04d_.bat",CMyRandom::NextInt(10000));
	ofstream outBatFile(fn);
	outBatFile<<"@echo off"<<endl;
	outBatFile<<"cd \""<<strPN_WorkPath<<"\" > nul"<<endl;
	outBatFile<<strCommandLine<<endl;
	outBatFile.clear();
	outBatFile.close();

	ret = system(fn);
	rv = system((string("del ") + string(fn) + string(" > nul")).c_str());

	return ret;
}

int CExternalTools::ConsoleTools::RunDosCommand( string strCommandLine )
{
	return RunDosCommand("", strCommandLine);
}

void CExternalTools::ConsoleTools::ClearCurrentLine()
{
	cout<<"\r"<<setw(79)<<" "<<"\r";
}

void CExternalTools::ConsoleTools::MakeCurrentLine(string strContext, bool fPrintEnter)
{
	ClearCurrentLine();
	cout<<strContext;
	if (fPrintEnter) cout<<endl;
}

void CExternalTools::ConsoleTools::OutputTextToStream( ostream& outStream, string strContext, bool fPrintEnter, bool fFlush )
{
	outStream<<strContext;
	if (fPrintEnter) outStream<<endl;
	if (fFlush) outStream.flush();
}
// [*] CSimpleMixedGaussianDistribution

void CSimpleMixedGaussianDistribution::myInit(int W, int H)
{
	this->W = W;
	this->H = H;
	imgPDF.assign(W, H, 1, 1);
	Clear();
}

void CSimpleMixedGaussianDistribution::Clear()
{
	imgPDF.fill(0.0);
}

void CSimpleMixedGaussianDistribution::AddNewGaussian(double weight, double ux, double uy, double vx, double vy)
{
	double DRAW_RANGE = 3.0;
	
	int lx, hx, ly, hy, ix, iy;
	double fx, fy;

	lx = (int)(ux - vx * DRAW_RANGE); if (lx < 0) lx = 0;
	hx = (int)(ux + vx * DRAW_RANGE); if (hx >= W) hx = W-1;
	ly = (int)(uy - vy * DRAW_RANGE); if (ly < 0) ly = 0;
	hy = (int)(uy + vy * DRAW_RANGE); if (hy >= H) hy = H-1;

	for ( iy = ly; iy <= hy; ++iy ) 
	{
		fy = CMyMath::gaussian(iy + 0.5 - uy, 0.0, vy);
		for ( ix = lx; ix <= hx; ++ix )
		{
			fx = CMyMath::gaussian(ix + 0.5 - ux, 0.0, vx);
			imgPDF.at(ix, iy) += weight * fx * fy;
		}
	}
}

